﻿//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using Newtonsoft.Json;

namespace Tools.Framework
{
    public static class XmlHelper
    {

        /// <summary>
        /// 是否合法xml文档
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static bool IsXmlDoc(string xml)
        {
            try
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.LoadXml(xml);
                return true;
            }
            catch
            {
                return false;
            }
        }



        #region 反序列化

        /// <summary> 
        /// 反序列化 
        /// </summary> 
        /// <param name="xmlString">XML字符串</param> 
        /// <returns></returns> 
        public static T XMLDeSerialize<T>(string xmlString) where T : new()
        {
            //XmlDocument xmldoc = new XmlDocument();
            //xmldoc.LoadXml(xmlString);
            //if (xmldoc.FirstChild.Name != typeof(T).Name)
            //{
            //    string rootname = typeof(T).Name;
            //    if ("List`1".Equals(typeof(T).Name))
            //    {
            //        rootname = "ArrayOfEmployee";
            //    }
            //    var childrens = xmldoc.FirstChild.ChildNodes;
            //    xmldoc.RemoveChild(xmldoc.FirstChild);
            //    var newnode = xmldoc.CreateElement(rootname,"");
            //    while (childrens.Count > 0)
            //    {
            //        newnode.AppendChild(childrens.Item(0));
            //    }
            //    xmldoc.AppendChild(newnode);
            //}

            //T cloneObject;

            //var buffer = new StringBuilder();
            //buffer.Append(xmldoc.OuterXml);

            //var serializer = new XmlSerializer(typeof(T));

            //using (TextReader reader = new StringReader(buffer.ToString()))
            //{
            //    Object obj = serializer.Deserialize(reader);
            //    cloneObject = (T)obj;
            //}

            //return cloneObject;

            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml(xmlString);
            if ("List`1".Equals(typeof (T).Name))
            {
                xmlString = xmlString.Replace(xmldoc.FirstChild.FirstChild.Name, "data");
                var str = xmlString.XmlToJsonstring();
                var data = JsonConvert.DeserializeObject<DateModelDTO<T>>(str);
                return data.root.data;
            }
            else
            {
                xmlString = xmlString.Replace(xmldoc.FirstChild.Name, "data");
                var str = xmlString.XmlToJsonstring();
                var data = JsonConvert.DeserializeObject<DateModelDTO<T>>(str);
                return data.data;
            }
        }

        public class DateModelDTO<T>
        {
            public root<T> root { set; get; }

            public T data { set; get; }
        }

        public class root<T>
        {
            public T data { set; get; }
        }
        #endregion


        #region 序列化XML

        /// <summary>
        /// 序列化为xml字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string XMLSerialize<T>(T entity)
        {
            StringBuilder buffer = new StringBuilder();
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            using (TextWriter writer = new StringWriter(buffer))
            {
                serializer.Serialize(writer, entity);
            }
            return buffer.ToString();
        }

        /// <summary>
        /// 识别需要序列化的类型
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static bool IsSimpleType(this Type type)
        {
            //识别需要序列化的类型  
            Type[] WriteTypes = new[]
            {
                typeof (string), typeof (DateTime?), typeof (Enum),
                typeof (decimal?), typeof (Guid), typeof (int?),typeof(double?),typeof(float?),typeof(long?)
            };
            return type.IsPrimitive || WriteTypes.Contains(type);
        }


        /// <summary>
        /// json转xml
        /// </summary>
        /// <param name="jsonstring"></param>
        /// <returns></returns>
        public static string JsonToXmlstring(this string jsonstring)
        {
            XmlDocument doc1 = JsonConvert.DeserializeXmlNode(jsonstring);
            return doc1.OuterXml;
        }
        /// <summary>
        /// xml转json
        /// </summary>
        /// <param name="jsonstring"></param>
        /// <returns></returns>
        public static string XmlToJsonstring(this string xmlstring)
        {
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml(xmlstring);
            string jsonstring = JsonConvert.SerializeXmlNode(xmldoc);
            return jsonstring;
        }
        /// <summary>
        /// json转xml
        /// </summary>
        /// <param name="xmldoc"></param>
        /// <returns></returns>
        public static string XmlToJson(this XmlDocument xmldoc)
        {
            return JsonConvert.SerializeXmlNode(xmldoc);
        }



        /// <summary>
        /// 匿名对象转xml
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static XmlDocument ToXml(this object input)
        {
            return input.ToXml(null);
        }
        /// <summary>
        /// 匿名对象转xml，并指定根节点名称  根节点默认为root
        /// </summary>
        /// <param name="input"></param>
        /// <param name="roolelementname"></param>
        /// <returns></returns>
        public static XmlDocument ToXml(this object input, string roolelementname)
        {

            XmlSerializer xmlSerializer = new XmlSerializer(input.GetType());
            MemoryStream my = new MemoryStream();
            xmlSerializer.Serialize(my, input);
            //转换  
            UTF8Encoding encoding = new UTF8Encoding();
            string strTemp = encoding.GetString(my.ToArray(), 0, my.ToArray().Length);
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml(strTemp);
            xmldoc.RemoveChild(xmldoc.FirstChild);
            return xmldoc;
        }
        #endregion



        #region 将XML转换为DATATABLE


        /// <summary> 
        /// 将XML转换为DATATABLE 
        /// </summary> 
        /// <param name="fileurl"></param>
        /// <returns></returns> 
        public static DataTable XmlToDataTabel(string fileurl)
        {
            try
            {
                DataSet ds = new DataSet();
                ds.ReadXml(fileurl);
                return ds.Tables[0];
            }
            catch (Exception )
            {
                return null;
            }
        }


        /// <summary>
        /// xml转换成数据字典
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static Dictionary<string, object> XmlToDictionary(string xml)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            if (!IsXmlDoc(xml))
            {
                return dictionary;
            }
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml(xml);

            if (xmldoc.ChildNodes.Count > 0)
            {
                if (xmldoc.FirstChild.Name.Equals("xml"))
                {
                    xmldoc.RemoveChild(xmldoc.FirstChild);
                }
            }

            if (xmldoc != null)
            {
                FindChildNodes(xmldoc, ref dictionary);
            }
            return dictionary;
        }

        private static void FindChildNodes(XmlNode xmldoc, ref Dictionary<string, object> dictionary)
        {
            for (int i = 0; i < xmldoc.ChildNodes.Count; i++)
            {
                if (xmldoc.ChildNodes.Count == 1 && xmldoc.ChildNodes.Item(0).NodeType == XmlNodeType.Text)
                {
                    if (!dictionary.ContainsKey(xmldoc.Name))
                        dictionary.Add(xmldoc.Name, xmldoc.InnerText);
                }
                else
                {
                    FindChildNodes(xmldoc.ChildNodes.Item(i), ref dictionary);
                }
            }
        }


        #endregion


        #region 保存到文件
        /// <summary>
        /// 保存到文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filepath">存储文件的绝对路径</param>
        /// <param name="entity"></param>
        public static void XmlSaveFile<T>(string filepath, T entity)
        {
            try
            {
                using (FileStream fs = new FileStream(filepath, FileMode.Create))
                {
                    XmlSerializer formatter = new XmlSerializer(typeof(T));
                    formatter.Serialize(fs, entity);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        #endregion
    }
}
